package com.gitee.wsl.common.more.ext.device

import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbManager
import android.hardware.usb.UsbRequest
import android.util.Log
import android.os.Process
import com.gitee.wsl.common.more.ext.device.UsbSerialPort.ControlLine
import com.gitee.wsl.common.more.ext.device.UsbSerialPort.Parity
import timber.log.Timber
import java.io.Closeable
import java.io.IOException
import java.io.InterruptedIOException
import java.nio.ByteBuffer
import java.util.EnumSet
import java.util.concurrent.Executors


class UsbSerial {
    @Throws(IOException::class)
    fun openUsb(manager: UsbManager,driver: UsbSerialDriver,callBack: SerialInputOutputManager.Listener) {
        val connection: UsbDeviceConnection = manager.openDevice(driver.device)?: return
        val serialPort = driver.ports[0] // Most devices have just one port (port 0)
        serialPort.open(connection)
        println("Dongle连接:已连接")
        serialPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, Parity.PARITY_NONE)
        val usbIoManager = SerialInputOutputManager(serialPort, object :
            SerialInputOutputManager.Listener {
            override fun onNewData(data: ByteArray) {
                callBack.onNewData(data)
            }

            override fun onRunError(e: Exception) {
                serialPort.close()
                println("Dongle连接:未连接")
                callBack.onRunError(e)
            }
        })
        //ThreadUtils.getIoPool().execute(usbIoManager)
        Executors.newSingleThreadExecutor().submit(usbIoManager);
    }
}

/**
 * Signals that a timeout has occurred on serial write.
 * Similar to SocketTimeoutException.
 *
 * {@see InterruptedIOException#bytesTransferred} may contain bytes transferred
 */
class SerialTimeoutException(s: String) : InterruptedIOException(s)


interface UsbSerialDriver {
    /*
     * Additional interface properties. Invoked thru reflection.
     *
        UsbSerialDriver(UsbDevice device);                  // constructor with device
        static Map<Integer, int[]> getSupportedDevices();
        static boolean probe(UsbDevice device);             // optional
     */
    /**
     * Returns the raw [UsbDevice] backing this port.
     *
     * @return the device
     */
    val device: UsbDevice

    /**
     * Returns all available ports for this device. This list must have at least
     * one entry.
     *
     * @return the ports
     */
    val ports: List<UsbSerialPort>
}

/**
 * Interface for a single serial port.
 *
 * @author mike wakerly (opensource@hoho.com)
 */
interface UsbSerialPort : Closeable {
    /** Values for setParameters(..., parity)  */
    enum class Parity{
        PARITY_NONE, PARITY_ODD, PARITY_EVEN, PARITY_MARK, PARITY_SPACE
    }

    /** Values for get[Supported]ControlLines()  */
    enum class ControlLine {
        RTS,
        CTS,
        DTR,
        DSR,
        CD,
        RI
    }

    /**
     * Returns the driver used by this port.
     */
    val driver: UsbSerialDriver?

    /**
     * Returns the currently-bound USB device.
     */
    val device: UsbDevice?

    /**
     * Port number within driver.
     */
    val portNumber: Int

    /**
     * Returns the write endpoint.
     * @return write endpoint
     */
    val writeEndpoint: UsbEndpoint?

    /**
     * Returns the read endpoint.
     * @return read endpoint
     */
    val readEndpoint: UsbEndpoint?

    /**
     * The serial number of the underlying UsbDeviceConnection, or `null`.
     *
     * @return value from [UsbDeviceConnection.getSerial]
     * @throws SecurityException starting with target SDK 29 (Android 10) if permission for USB device is not granted
     */
    val serial: String?

    /**
     * Opens and initializes the port. Upon success, caller must ensure that
     * [.close] is eventually called.
     *
     * @param connection an open device connection, acquired with
     * [UsbManager.openDevice]
     * @throws IOException on error opening or initializing the port.
     */
    @Throws(IOException::class)
    fun open(connection: UsbDeviceConnection)

    /**
     * Closes the port and [UsbDeviceConnection]
     *
     * @throws IOException on error closing the port.
     */
    @Throws(IOException::class)
    override fun close()

    /**
     * Reads as many bytes as possible into the destination buffer.
     *
     * @param dest the destination byte buffer
     * @param timeout the timeout for reading in milliseconds, 0 is infinite
     * @return the actual number of bytes read
     * @throws IOException if an error occurred during reading
     */
    @Throws(IOException::class)
    fun read(dest: ByteArray, timeout: Int): Int

    /**
     * Reads bytes with specified length into the destination buffer.
     *
     * @param dest the destination byte buffer
     * @param length the maximum length of the data to read
     * @param timeout the timeout for reading in milliseconds, 0 is infinite
     * @return the actual number of bytes read
     * @throws IOException if an error occurred during reading
     */
    @Throws(IOException::class)
    fun read(dest: ByteArray, length: Int, timeout: Int): Int

    /**
     * Writes as many bytes as possible from the source buffer.
     *
     * @param src the source byte buffer
     * @param timeout the timeout for writing in milliseconds, 0 is infinite
     * @throws SerialTimeoutException if timeout reached before sending all data.
     * ex.bytesTransferred may contain bytes transferred
     * @throws IOException if an error occurred during writing
     */
    @Throws(IOException::class)
    fun write(src: ByteArray, timeout: Int)

    /**
     * Writes bytes with specified length from the source buffer.
     *
     * @param src the source byte buffer
     * @param length the length of the data to write
     * @param timeout the timeout for writing in milliseconds, 0 is infinite
     * @throws SerialTimeoutException if timeout reached before sending all data.
     * ex.bytesTransferred may contain bytes transferred
     * @throws IOException if an error occurred during writing
     */
    @Throws(IOException::class)
    fun write(src: ByteArray, length: Int, timeout: Int)

    /**
     * Sets various serial port parameters.
     *
     * @param baudRate baud rate as an integer, for example `115200`.
     * @param dataBits one of [.DATABITS_5], [.DATABITS_6],
     * [.DATABITS_7], or [.DATABITS_8].
     * @param stopBits one of [.STOPBITS_1], [.STOPBITS_1_5], or [.STOPBITS_2].
     * @param parity one of [.PARITY_NONE], [.PARITY_ODD],
     * [.PARITY_EVEN], [.PARITY_MARK], or [.PARITY_SPACE].
     * @throws IOException on error setting the port parameters
     * @throws UnsupportedOperationException if values are not supported by a specific device
     */
    @Throws(IOException::class)
    fun setParameters(baudRate: Int, dataBits: Int, stopBits: Int, parity: Parity)

    @get:Throws(IOException::class)
    val cD: Boolean

    @get:Throws(IOException::class)
    val cTS: Boolean

    @get:Throws(IOException::class)
    val dSR: Boolean

    @get:Throws(IOException::class)
    @set:Throws(IOException::class)
    var dTR: Boolean

    @get:Throws(IOException::class)
    val rI: Boolean

    @get:Throws(IOException::class)
    @set:Throws(IOException::class)
    var rTS: Boolean

    @get:Throws(IOException::class)
    val controlLines: EnumSet<ControlLine>

    @get:Throws(IOException::class)
    val supportedControlLines: EnumSet<ControlLine>

    /**
     * Purge non-transmitted output data and / or non-read input data.
     *
     * @param purgeWriteBuffers `true` to discard non-transmitted output data
     * @param purgeReadBuffers `true` to discard non-read input data
     * @throws IOException if an error occurred during flush
     * @throws UnsupportedOperationException if not supported
     */
    @Throws(IOException::class)
    fun purgeHwBuffers(purgeWriteBuffers: Boolean, purgeReadBuffers: Boolean)

    /**
     * send BREAK condition.
     *
     * @param value set/reset
     */
    @Throws(IOException::class)
    fun setBreak(value: Boolean)

    /**
     * Returns the current state of the connection.
     */
    val isOpen: Boolean

    companion object {
        /** 5 data bits.  */
        const val DATABITS_5 = 5

        /** 6 data bits.  */
        const val DATABITS_6 = 6

        /** 7 data bits.  */
        const val DATABITS_7 = 7

        /** 8 data bits.  */
        const val DATABITS_8 = 8

        /** No parity.  */
        const val PARITY_NONE = 0

        /** Odd parity.  */
        const val PARITY_ODD = 1

        /** Even parity.  */
        const val PARITY_EVEN = 2

        /** Mark parity.  */
        const val PARITY_MARK = 3

        /** Space parity.  */
        const val PARITY_SPACE = 4

        /** 1 stop bit.  */
        const val STOPBITS_1 = 1

        /** 1.5 stop bits.  */
        const val STOPBITS_1_5 = 3

        /** 2 stop bits.  */
        const val STOPBITS_2 = 2
    }
}

/**
 * A base class shared by several driver implementations.
 *
 * @author mike wakerly (opensource@hoho.com)
 */
abstract class CommonUsbSerialPort(override val device: UsbDevice, override val portNumber: Int) : UsbSerialPort {

    // non-null when open()
    protected var mConnection: UsbDeviceConnection? = null
    override var readEndpoint: UsbEndpoint? = null
        protected set
    override var writeEndpoint: UsbEndpoint? = null
        protected set
    protected var mUsbRequest: UsbRequest? = null

    /**
     * Internal write buffer.
     * Guarded by [.mWriteBufferLock].
     * Default length = mReadEndpoint.getMaxPacketSize()
     */
    protected  var mWriteBuffer: ByteArray?=null
    protected val mWriteBufferLock = Any()
    override fun toString(): String {
        return String.format(
            "<%s device_name=%s device_id=%s port_number=%s>",
            javaClass.simpleName, device.deviceName,
            device.deviceId, portNumber
        )
    }

    override val serial: String
        /**
         * Returns the device serial number
         * @return serial number
         */
        get() = mConnection!!.serial

    /**
     * Sets the size of the internal buffer used to exchange data with the USB
     * stack for write operations.  Most users should not need to change this.
     *
     * @param bufferSize the size in bytes, <= 0 resets original size
     */
    fun setWriteBufferSize(bufferSize: Int) {
        var bufferSize = bufferSize
        synchronized(mWriteBufferLock) {
            if (bufferSize <= 0) {
                if (writeEndpoint != null) {
                    bufferSize = writeEndpoint!!.maxPacketSize
                } else {
                    mWriteBuffer = null
                    return
                }
            }
            if (mWriteBuffer != null && bufferSize == mWriteBuffer!!.size) {
                return
            }
            mWriteBuffer = ByteArray(bufferSize)
        }
    }

    @Throws(IOException::class)
    override fun open(connection: UsbDeviceConnection) {
        if (mConnection != null) {
            throw IOException("Already open")
        }
        requireNotNull(connection) { "Connection is null" }
        mConnection = connection
        try {
            openInt()
            if (readEndpoint == null || writeEndpoint == null) {
                throw IOException("Could not get read & write endpoints")
            }
            mUsbRequest = UsbRequest()
            mUsbRequest!!.initialize(mConnection, readEndpoint)
        } catch (e: Exception) {
            try {
                close()
            } catch (ignored: Exception) {
            }
            throw e
        }
    }

    @Throws(IOException::class)
    protected abstract fun openInt()

    @Throws(IOException::class)
    override fun close() {
        if (mConnection == null) {
            throw IOException("Already closed")
        }
        try {
            mUsbRequest!!.cancel()
        } catch (ignored: Exception) {
        }
        mUsbRequest = null
        try {
            closeInt()
        } catch (ignored: Exception) {
        }
        try {
            mConnection!!.close()
        } catch (ignored: Exception) {
        }
        mConnection = null
    }

    protected abstract fun closeInt()

    /**
     * use simple USB request supported by all devices to test if connection is still valid
     */
    @Throws(IOException::class)
    protected fun testConnection() {
        if (mConnection == null || mUsbRequest == null) {
            throw IOException("Connection closed")
        }
        val buf = ByteArray(2)
        val len = mConnection!!.controlTransfer(
            0x80 /*DEVICE*/,
            0 /*GET_STATUS*/,
            0,
            0,
            buf,
            buf.size,
            200
        )
        if (len < 0) throw IOException("USB get_status request failed")
    }

    @Throws(IOException::class)
    override fun read(dest: ByteArray, timeout: Int): Int {
        require(dest.isNotEmpty()) { "Read buffer too small" }
        return read(dest, dest.size, timeout)
    }

    @Throws(IOException::class)
    override fun read(dest: ByteArray, length: Int, timeout: Int): Int {
        return read(dest, length, timeout, true)
    }

    @Throws(IOException::class)
    protected fun read(dest: ByteArray, length: Int, timeout: Int, testConnection: Boolean): Int {
        var length = length
        if (mConnection == null || mUsbRequest == null) {
            throw IOException("Connection closed")
        }
        require(length > 0) { "Read length too small" }
        length = Math.min(length, dest.size)
        val nread: Int
        if (timeout != 0) {
            // bulkTransfer will cause data loss with short timeout + high baud rates + continuous transfer
            //   https://stackoverflow.com/questions/9108548/android-usb-host-bulktransfer-is-losing-data
            // but mConnection.requestWait(timeout) available since Android 8.0 es even worse,
            // as it crashes with short timeout, e.g.
            //   A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x276a in tid 29846 (pool-2-thread-1), pid 29618 (.usbserial.test)
            //     /system/lib64/libusbhost.so (usb_request_wait+192)
            //     /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
            // data loss / crashes were observed with timeout up to 200 msec
            val endTime: Long = if (testConnection) MonotonicClock.millis() + timeout else 0
            val readMax = Math.min(length, MAX_READ_SIZE)
            nread = mConnection!!.bulkTransfer(readEndpoint, dest, readMax, timeout)
            // Android error propagation is improvable:
            //  nread == -1 can be: timeout, connection lost, buffer to small, ???
            if (nread == -1 && testConnection && MonotonicClock.millis() < endTime) testConnection()
        } else {
            val buf = ByteBuffer.wrap(dest, 0, length)
            if (!mUsbRequest!!.queue(buf, length)) {
                throw IOException("Queueing USB request failed")
            }
            val response = mConnection!!.requestWait()
                ?: throw IOException("Waiting for USB request failed")
            nread = buf.position()
            // Android error propagation is improvable:
            //   response != null & nread == 0 can be: connection lost, buffer to small, ???
            if (nread == 0) {
                testConnection()
            }
        }
        return Math.max(nread, 0)
    }

    @Throws(IOException::class)
    override fun write(src: ByteArray, timeout: Int) {
        write(src, src.size, timeout)
    }

    @Throws(IOException::class)
    override fun write(src: ByteArray, length: Int, timeout: Int) {
        var length = length
        var offset = 0
        val endTime: Long = if (timeout == 0) 0 else MonotonicClock.millis() + timeout
        length = Math.min(length, src.size)
        if (mConnection == null) {
            throw IOException("Connection closed")
        }
        while (offset < length) {
            var requestTimeout: Int
            val requestLength: Int
            val actualLength: Int
            synchronized(mWriteBufferLock) {
                if (mWriteBuffer == null) {
                    mWriteBuffer = ByteArray(writeEndpoint!!.maxPacketSize)
                }
                requestLength = Math.min(length - offset, mWriteBuffer!!.size)
                val writeBuffer: ByteArray = if (offset == 0) {
                    src
                } else {
                    // bulkTransfer does not support offsets, make a copy.
                    System.arraycopy(src, offset, mWriteBuffer, 0, requestLength)
                    mWriteBuffer
                }!!
                if (timeout == 0 || offset == 0) {
                    requestTimeout = timeout
                } else {
                    requestTimeout = (endTime - MonotonicClock.millis()) as Int
                    if (requestTimeout == 0) requestTimeout = -1
                }
                actualLength = if (requestTimeout < 0) {
                    -2
                } else {
                    mConnection!!.bulkTransfer(
                        writeEndpoint,
                        writeBuffer,
                        requestLength,
                        requestTimeout
                    )
                }
            }
            if (DEBUG) {
                Timber.tag(TAG).d("Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + length + " timeout " + requestTimeout)
            }
            if (actualLength <= 0) {
                if (timeout != 0 && MonotonicClock.millis() >= endTime) {
                    val ex =
                        SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.size + ", rc=" + actualLength)
                    ex.bytesTransferred = offset
                    throw ex
                } else {
                    throw IOException("Error writing $requestLength bytes at offset $offset of total $length")
                }
            }
            offset += actualLength
        }
    }

    override val isOpen: Boolean
        get() = mConnection != null

    @Throws(IOException::class)
    abstract override fun setParameters(
        baudRate: Int,
        dataBits: Int,
        stopBits: Int,
        parity: Parity
    )

    @get:Throws(IOException::class)
    override val cD: Boolean
        get() {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    override val cTS: Boolean
        get() {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    override val dSR: Boolean
        get() {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    @set:Throws(IOException::class)
    override var dTR: Boolean
        get() {
            throw UnsupportedOperationException()
        }
        set(value) {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    override val rI: Boolean
        get() {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    @set:Throws(IOException::class)
    override var rTS: Boolean
        get() {
            throw UnsupportedOperationException()
        }
        set(value) {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    override val controlLines: EnumSet<ControlLine>
        get() {
            throw UnsupportedOperationException()
        }

    @get:Throws(IOException::class)
    abstract override val supportedControlLines: EnumSet<ControlLine>

    @Throws(IOException::class)
    override fun purgeHwBuffers(purgeWriteBuffers: Boolean, purgeReadBuffers: Boolean) {
        throw UnsupportedOperationException()
    }

    @Throws(IOException::class)
    override fun setBreak(value: Boolean) {
        throw UnsupportedOperationException()
    }

    companion object {
        var DEBUG = false
        private val TAG = CommonUsbSerialPort::class.java.simpleName
        private const val MAX_READ_SIZE = 16 * 1024 // = old bulkTransfer limit
    }
}

object MonotonicClock {
    private const val NS_PER_MS: Long = 1000000
    fun millis(): Long {
        return System.nanoTime() / NS_PER_MS
    }
}

/**
 * Utility class which services a [UsbSerialPort] in its [.run] method.
 *
 * @author mike wakerly (opensource@hoho.com)
 */
class SerialInputOutputManager : Runnable {
    enum class State {
        STOPPED,
        RUNNING,
        STOPPING
    }

    /**
     * default read timeout is infinite, to avoid data loss with bulkTransfer API
     */
    private var mReadTimeout = 0
    var writeTimeout = 0
    private val mReadBufferLock = Any()
    private val mWriteBufferLock = Any()
    private var mReadBuffer // default size = getReadEndpoint().getMaxPacketSize()
            : ByteBuffer
    private var mWriteBuffer = ByteBuffer.allocate(BUFSIZ)
    private var mThreadPriority: Int = Process.THREAD_PRIORITY_URGENT_AUDIO

    @get:Synchronized
    var state = State.STOPPED // Synchronized by 'this'
        private set

    @get:Synchronized
    @set:Synchronized
    var listener: Listener? = null // Synchronized by 'this'
    private val mSerialPort: UsbSerialPort

    interface Listener {
        /**
         * Called when new incoming data is available.
         */
        fun onNewData(data: ByteArray)

        /**
         * Called when [SerialInputOutputManager.run] aborts due to an error.
         */
        fun onRunError(e: java.lang.Exception)
    }

    constructor(serialPort: UsbSerialPort) {
        mSerialPort = serialPort
        mReadBuffer = ByteBuffer.allocate(serialPort.readEndpoint!!.maxPacketSize)
    }

    constructor(serialPort: UsbSerialPort, listener: Listener?) {
        mSerialPort = serialPort
        this.listener = listener
        mReadBuffer = ByteBuffer.allocate(serialPort.readEndpoint!!.maxPacketSize)
    }

    /**
     * setThreadPriority. By default a higher priority than UI thread is used to prevent data loss
     *
     * @param threadPriority  see [Process.setThreadPriority]
     */
    fun setThreadPriority(threadPriority: Int) {
        check(state == State.STOPPED) { "threadPriority only configurable before SerialInputOutputManager is started" }
        mThreadPriority = threadPriority
    }

    var readTimeout: Int
        get() = mReadTimeout
        /**
         * read/write timeout
         */
        set(timeout) {
            // when set if already running, read already blocks and the new value will not become effective now
            check(!(mReadTimeout == 0 && timeout != 0 && state != State.STOPPED)) { "readTimeout only configurable before SerialInputOutputManager is started" }
            mReadTimeout = timeout
        }
    var readBufferSize: Int
        get() = mReadBuffer.capacity()
        /**
         * read/write buffer size
         */
        set(bufferSize) {
            if (readBufferSize == bufferSize) return
            synchronized(mReadBufferLock) {
                mReadBuffer = ByteBuffer.allocate(bufferSize)
            }
        }
    var writeBufferSize: Int
        get() = mWriteBuffer.capacity()
        set(bufferSize) {
            if (writeBufferSize == bufferSize) return
            synchronized(mWriteBufferLock) {
                val newWriteBuffer = ByteBuffer.allocate(bufferSize)
                if (mWriteBuffer.position() > 0) newWriteBuffer.put(
                    mWriteBuffer.array(),
                    0,
                    mWriteBuffer.position()
                )
                mWriteBuffer = newWriteBuffer
            }
        }

    /**
     * when using writeAsync, it is recommended to use readTimeout != 0,
     * else the write will be delayed until read data is available
     */
    fun writeAsync(data: ByteArray) {
        synchronized(mWriteBufferLock) { mWriteBuffer.put(data) }
    }

    /**
     * start SerialInputOutputManager in separate thread
     */
    fun start() {
        check(state == State.STOPPED) { "already started" }
        Thread(this, this.javaClass.simpleName).start()
    }

    /**
     * stop SerialInputOutputManager thread
     *
     * when using readTimeout == 0 (default), additionally use usbSerialPort.close() to
     * interrupt blocking read
     */
    @Synchronized
    fun stop() {
        if (state == State.RUNNING) {
            Log.i(TAG, "Stop requested")
            state = State.STOPPING
        }
    }

    /**
     * Continuously services the read and write buffers until [.stop] is
     * called, or until a driver exception is raised.
     */
    override fun run() {
        synchronized(this) {
            check(state == State.STOPPED) { "Already running" }
            state = State.RUNNING
        }
        Log.i(TAG, "Running ...")
        try {
            if (mThreadPriority != Process.THREAD_PRIORITY_DEFAULT) Process.setThreadPriority(
                mThreadPriority
            )
            while (true) {
                if (state != State.RUNNING) {
                    Log.i(TAG, "Stopping mState=" + state)
                    break
                }
                step()
            }
        } catch (e: java.lang.Exception) {
            Log.w(TAG, "Run ending due to exception: " + e.message, e)
            val listener = listener
            listener?.onRunError(e)
        } finally {
            synchronized(this) {
                state = State.STOPPED
                Log.i(TAG, "Stopped")
            }
        }
    }

    @Throws(IOException::class)
    private fun step() {
        // Handle incoming data.
        var buffer: ByteArray?=null
        synchronized(mReadBufferLock) { buffer = mReadBuffer.array() }
        var len = mSerialPort.read(buffer!!, mReadTimeout)
        if (len > 0) {
            if (DEBUG) {
                Log.d(TAG, "Read data len=$len")
            }
            val listener = listener
            if (listener != null) {
                val data = ByteArray(len)
                System.arraycopy(buffer, 0, data, 0, len)
                listener.onNewData(data)
            }
        }

        // Handle outgoing data.
        buffer = null
        synchronized(mWriteBufferLock) {
            len = mWriteBuffer.position()
            if (len > 0) {
                buffer = ByteArray(len)
                mWriteBuffer.rewind()
                mWriteBuffer[buffer, 0, len]
                mWriteBuffer.clear()
            }
        }
        if (buffer != null) {
            if (DEBUG) {
                Log.d(TAG, "Writing data len=$len")
            }
            mSerialPort.write(buffer!!, writeTimeout)
        }
    }

    companion object {
        var DEBUG = false
        private val TAG = SerialInputOutputManager::class.java.simpleName
        private const val BUFSIZ = 4096
    }
}